-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Load plugin immediately #6673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Load plugin immediately #6673
Conversation
56b0a1e
to
ef48b92
Compare
Rebased. |
If I have version X of plugin |
Correct.
Yes. Two different versions of the same gem are loaded in the situation.
I agree with you. How about preventing loading Is this behavior acceptable? |
I've implemented the behavior. What do you think about this? |
@kou I'm fine with the updated behavior, thanks. I will review the PR in a few days, just to give other maintainers time to leave their feedback or raise their objections (if any). |
Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seem to be some error output when running tests now, can you have a look? Could those point to some bad side effect on real usage?
/home/runner/work/rubygems/rubygems/tmp/test_rubygems_20230516-2057-9o50ny/gemhome/gems/a-2/lib/rubygems_plugin.rb
Error loading RubyGems plugin "/home/runner/work/rubygems/rubygems/tmp/test_rubygems_20230516-2057-gehefu/gemhome/plugins/a_plugin.rb": cannot load such file -- (LoadError)
Error loading RubyGems plugin "/home/runner/work/rubygems/rubygems/tmp/test_rubygems_20230516-2057-oovia/gemhome/plugins/a_plugin.rb": cannot load such file -- (LoadError)
Error loading RubyGems plugin "/home/runner/work/rubygems/rubygems/tmp/test_rubygems_20230516-2057-rpqs7e/gemhome/plugins/a_plugin.rb": cannot load such file -- (LoadError)
|
||
run_post_install_hooks | ||
|
||
load_plugin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If run_post_install_hooks
happened before load_plugin
, then any post install hooks potentially registered by the gem would be run immediately too, right?
For example, say the rdoc
gem installs a plugin that generates documentation after gems are installed, then gem install rdoc
would immediately generate docs for rdoc
itself.
Did you consider this? Do you think it would be desirable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sorry. I didn't consider this.
rdoc
(and yard
) use done_installing
hook not post_install
hook but I can understand what you want to say.
I'll move load_plugin
BEFORE run_post_install_hooks
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
BTW, I think that we can remove https://github.com/rubygems/rubygems/blob/master/lib/rubygems/rdoc.rb and implement this by RubyGems plugin in RDoc after we merge this pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I'm not fully sure which behavior is best, but I guess running hooks for the gem right after installing is inline with the spirit of this PR.
Regarding RDoc, I think that's what was proposed by #6021, and it makes sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I didn't notice #6021.
I'll work on it after we merge this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation: ruby/rdoc#1171
db51e60
to
fd454f7
Compare
Sorry. I missed them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! This looks good to me, let's hope it doesn't create any bad side effects. But it something unexpected comes up, we can consider it later.
Please mention me when we found any unexpected side effect. |
We can install RubyGems plugin by "gem install XXX". The installed plugin is used from the NEXT "gem ...". For example, "gem install gem-src kaminari" doesn't use gem-src plugin for kaminari. "gem install gem-src && gem install kaminari" uses gem-src plugin for kaminari. How about loading a plugin immediately when the plugin is installed? If this proposal is implemented, "gem install gem-src kaminari" works like "gem install gem-src && gem install kaminari".
Load plugin immediately (cherry picked from commit 09e839c)
Problems 1. If there are braking changes in RDoc, RubyGems is also broken. 2. When we maintain RDoc, we have to change RubyGems. The reason why they are happened is that RubyGems creates documents about a gem with installing it. Note that RubyGems uses functions of RDoc to create documents. Specifically, - Creating documents is executed by `rubygems/lib/rubygems/rdoc.rb`. - `::RDoc::RubygemsHook` which is defined by RDoc is called by the file. Solution RubyGems has the plugin system. If a gem includes `rubygems_plugin.rb`, RubyGems loads it. RubyGems executes a process defined in it while installing gems, uninstalling gems or other events. We can use the system to solve the problems. The root cause is RubyGems directly references the class of RDoc. We can remove the root cause by making RDoc RubyGems plugin. Alternatively `rubygems_plugin.rb` creates documents about gems. FAQ Q1. Do we need to change codes of RubyGems? A. No, we don't. If we change codes of RubyGems, we can't keep a compatibility. Example: If we delete codes that uses `RDoc::RubygemsHook` in `rubygems/lib/rubygems/rdoc.rb`, documentations are not created with old RDoc. Q2. When can we delete `rubygems/lib/rubygems/rdoc.rb`? A. We can delete it when all users use RDoc including `rubygems_plugin`. Next ruby version is 3.4. If it includes the RDoc including `rubygems_plugin`, we can delete `rubygems/lib/rubygems/rdoc.rb` after ruby 3.3 is EOL. Q3. Is it a breaking change that Rubygems creates documents with rubygems_plugin not RDoc::RubygemsHook? A. If we simply implement this approach, we move the implementation from `rdoc/lib/rdoc/rubygems_hook.rb` to `rubygems_plugin.rb`. This way can be breaking change. It seems to be fine that we just need to delete `rdoc/rubygems_hook.rb` but it doesn't work. It generates multiple documents. `rubygems/lib/rubygems/rdoc.rb` has the following code. ``` begin require "rdoc/rubygems_hook" # ... rescue LoadError end ``` This code ignores RDoc related processes when `rdoc/rubygems_hook` can't be required. But, this 'require' is not failed. This is because Ruby installs Rdoc as a default gem. So, Rdoc installed as a default gem generates documents and one installed as a normal gem does it too. If you think that this behavior is accectable, we can just delete `rdoc/rubygems_hook.rb`. What do you think about this approach? In this change, we take another approach to solve the problem that creates multiple documents. The reason why the approach that just deletes `rdoc/rubygems.rb` creates multiple documents is `Gem.done_installing(&Gem::RDoc.method(:generation_hook))` in `rubygems/rdoc.rb`. `rubygems/rdoc.rb` が Gem.done_installing しているところで ドキュメント生成がデフォルト gem によって行われているので、既存の Rubygems が require している RDoc::RubygemsHook は何も処理を実行しないようにしている。 ↑ 次回: - 動作確認について、手順、結果 Note When RDoc and other gem were installed, RubyGems plugin of RDoc wasn't executed. For example ``` gem install rdoc pkg-config ``` Expected Installing RDoc creates a document of pkg-config. Actual Installed RDoc creates a document of pkg-config. See also. ruby/rubygems#6673 | RDoc / rubyGems | New | Old | | changed | A | A | | current | A | A | Because RDoc is default gem, インストール済みの RDoc でドキュメント生成される。 ただし、この RDoc のバージョン以降を一度インストールすれば、 以降は Plugin によってドキュメント生成がされる。 旧バージョンとの違いは、 Plugin がドキュメント生成するかどうかの違いで、 アウトプットには違いがない。 ======= テスト結果の説明のために、 rdoc 未インストールの状態で、gem install rdoc pkg-config を実行してみる。 このパターンでは実行結果が Expect になるはず。 => Ruby 3.x 以降で RDoc が default gem から bundled gem になる提案がある。 将来の話、というテイでテストしておくのもあり? => 実際にテストしてみたところ、 installing の rdoc で plugin を利用して document 生成がされた。 テスト方法 default gem がない状態を再現する方法 1. Move to a directory includes default gems. $ cd $(ruby -e 'print RbConfig::CONFIG["rubylibdir"]') 2. Rename 'rdoc' and 'rdoc.rb'. $ mv rdoc{,.bk} $ mv rdoc.rb{,.bk} 3. Move to a directory includes specifications of default gems. $ cd $(gem environment gemdir)/specifications/default 4. Rename 'rdoc-<versions>.gemspec'. $ mv $(echo rdoc-*.gemspec){,.bk}
Because RubyGems is old. ruby/rubygems#6673 is needed.
What was the end-user or developer problem that led to this PR?
We can install RubyGems plugin by "gem install XXX". The installed plugin is used from the NEXT "gem ...".
For example, "gem install gem-src kaminari" doesn't use gem-src plugin for kaminari. "gem install gem-src && gem install kaminari" uses gem-src plugin for kaminari.
What is your fix for the problem, implemented in this PR?
How about loading a plugin immediately when the plugin is installed? If this proposal is implemented, "gem install gem-src kaminari" works like "gem install gem-src && gem install kaminari".
Make sure the following tasks are checked